home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 021-030 / amok22 / lists / lists.mod < prev    next >
Text File  |  1993-11-04  |  8KB  |  339 lines

  1. (**********************************************************************
  2.  
  3.     :Program.    Lists.mod
  4.     :Contents.   Generic data type: List
  5.     :Author.     Nicolas Benezan [bne]
  6.     :Address.    Postwiesenstr. 2, D7000 Stuttgart 60
  7.     :Phone.      711/333679
  8.     :Copyright.  Public Domain
  9.     :Language.   Modula-2
  10.     :Translator. M2Amiga AMSoft 3.2d
  11.     :Imports.    TaskMemory [bne]
  12.     :History.    V1.0 [mif] 13.Sep.1988
  13.     :History.    V1.1 [bne] 8.Feb.1989 (V1.0 modified)
  14.     :History.    V2.0d [bne] 25.Feb.1989 (complete new version)
  15.     :History.    V2.1a [bne] 22.Mar.1989 (Bug in CreateList() fixed)
  16.  
  17. **********************************************************************)
  18.  
  19. IMPLEMENTATION MODULE Lists;
  20.  
  21. FROM SYSTEM     IMPORT BYTE,ADR,ADDRESS;
  22. FROM Exec       IMPORT MinList,ListPtr,MinNode,NodePtr,AddTail,RemHead,
  23.                 Insert,Remove,CopyMem;
  24. FROM TaskMemory IMPORT Allocate,Deallocate;
  25.  
  26. TYPE    List=POINTER TO Root;
  27.         Root=RECORD
  28.           header:MinList;
  29.           numEntries:CARDINAL;
  30.           listOk:BOOLEAN;
  31.         END;
  32.  
  33. PROCEDURE CreateList(VAR list:List):BOOLEAN;
  34. BEGIN
  35.   ListsAllocProc(list,SIZE(Root));
  36.   IF list#NIL THEN
  37.     WITH list^ DO
  38.       WITH header DO    (* NewList() macro *)
  39.         head:=ADR(tail);
  40.         tail:=NIL;
  41.         tailPred:=ADR(head);
  42.       END;
  43.       numEntries:=0;
  44.       listOk:=TRUE;
  45.     END;
  46.     RETURN TRUE;
  47.   ELSE
  48.     RETURN FALSE;
  49.   END;
  50. END CreateList;
  51.  
  52. PROCEDURE AppendEntry(list:List;
  53.                       DataSize:CARDINAL;
  54.                       DataAddr:ADDRESS);
  55. VAR     NewEntry:EntryPtr;
  56. BEGIN
  57.   ListsAllocProc(NewEntry,SIZE(Entry));
  58.   IF NewEntry#NIL THEN
  59.     WITH NewEntry^ DO
  60.       dataPtr:=DataAddr;
  61.       dataSize:=DataSize;
  62.     END;
  63.     AddTail(ADDRESS(list),NewEntry);
  64.     INC(list^.numEntries);
  65.   ELSE
  66.     list^.listOk:=FALSE;
  67.   END;
  68. END AppendEntry;
  69.  
  70. PROCEDURE AppendEntryC(list:List;
  71.                    VAR Data:ARRAY OF BYTE);
  72. VAR     DataAddr:ADDRESS;
  73.         DataSize:CARDINAL;
  74. BEGIN
  75.   DataSize:=HIGH(Data)+1;
  76.   IF list^.listOk THEN
  77.     ListsAllocProc(DataAddr,DataSize);
  78.     IF DataAddr#NIL THEN
  79.       CopyMem(ADR(Data),DataAddr,DataSize);
  80.       AppendEntry(list,DataSize,DataAddr);
  81.       IF list^.listOk THEN
  82.         RETURN
  83.       ELSE
  84.         ListsDeallocProc(DataAddr);
  85.       END;
  86.     ELSE
  87.       list^.listOk:=FALSE;
  88.     END;
  89.   END;
  90. END AppendEntryC;
  91.  
  92.  
  93. PROCEDURE RemoveEntry(list:List;
  94.                   VAR entry:EntryPtr);
  95. BEGIN
  96.   IF entry#NIL THEN (* one of the most exciting *)
  97.     Remove(entry);  (* system crashes: Remove(NIL) *)
  98.     DEC(list^.numEntries);
  99.     ListsDeallocProc(entry);
  100.     entry:=NIL; (* if we used Heap or TaskMemory or MemSystem,
  101.                    this wouldn't be necessary *)
  102.   ELSE
  103.     list^.listOk:=FALSE;
  104.   END;
  105. END RemoveEntry;
  106.  
  107. PROCEDURE DeleteEntry(list:List;
  108.                       entry:EntryPtr);
  109. BEGIN
  110.   IF entry#NIL THEN
  111.     ListsDeallocProc(entry^.dataPtr);
  112.     RemoveEntry(list,entry);
  113.   END;
  114. END DeleteEntry;
  115.  
  116. PROCEDURE DeleteList(VAR list:List);
  117. BEGIN
  118.   WITH list^.header DO
  119.     WHILE head^.succ#NIL DO
  120.       DeleteEntry(list,ADDRESS(head));
  121.     END;
  122.   END;
  123. END DeleteList;
  124.  
  125. PROCEDURE InsertEntry(list:List;
  126.                       Position:EntryPtr;
  127.                       DataSize:CARDINAL;
  128.                       DataAddr:ADDRESS);
  129. VAR     NewEntry:EntryPtr;
  130. BEGIN
  131.   ListsAllocProc(NewEntry,SIZE(Entry));
  132.   IF NewEntry#NIL THEN
  133.     WITH NewEntry^ DO
  134.       dataPtr:=DataAddr;
  135.       dataSize:=DataSize;
  136.     END;
  137.     Insert(ADDRESS(list),NewEntry,Position^.node.pred);
  138.     INC(list^.numEntries);
  139.   ELSE
  140.     list^.listOk:=FALSE;
  141.   END;
  142. END InsertEntry;
  143.  
  144. PROCEDURE InsertEntryC(list:List;
  145.                        Position:EntryPtr;
  146.                    VAR Data:ARRAY OF BYTE);
  147. VAR     DataAddr:ADDRESS;
  148.         DataSize:CARDINAL;
  149. BEGIN
  150.   IF list^.listOk THEN
  151.     DataSize:=HIGH(Data)+1;
  152.     ListsAllocProc(DataAddr,DataSize);
  153.     IF DataAddr#NIL THEN
  154.       CopyMem(ADR(Data),DataAddr,DataSize);
  155.       InsertEntry(list,Position,DataSize,DataAddr);
  156.       IF list^.listOk THEN
  157.         RETURN
  158.       ELSE
  159.         ListsDeallocProc(DataAddr);
  160.       END;
  161.     ELSE
  162.       list^.listOk:=FALSE;
  163.     END;
  164.   END;
  165. END InsertEntryC;
  166.  
  167. PROCEDURE ListOk(list:List):BOOLEAN;
  168. VAR     oldOk:BOOLEAN;
  169. BEGIN
  170.   WITH list^ DO
  171.     oldOk:=listOk;
  172.     listOk:=TRUE;
  173.   END;
  174.   RETURN oldOk;
  175. END ListOk;
  176.  
  177. PROCEDURE EntriesInList(list:List):CARDINAL;
  178. BEGIN
  179.   RETURN list^.numEntries;
  180. END EntriesInList;
  181.  
  182. PROCEDURE ReadEntry(list:List;
  183.                     entry:EntryPtr;
  184.                 VAR DataSize:CARDINAL;
  185.                 VAR DataAddr:ADDRESS);
  186. BEGIN
  187.   IF entry#NIL THEN
  188.     WITH entry^ DO
  189.       DataSize:=dataSize;
  190.       DataAddr:=dataPtr;
  191.     END;
  192.   ELSE
  193.     DataSize:=0;
  194.     DataAddr:=NIL;
  195.     list^.listOk:=FALSE;
  196.   END;
  197. END ReadEntry;
  198.  
  199. PROCEDURE ReadEntryC(list:List;
  200.                      entry:EntryPtr;
  201.                  VAR Data:ARRAY OF BYTE);
  202. VAR     DataAddr:ADDRESS;
  203.         DataSize:CARDINAL;
  204. BEGIN
  205.   ReadEntry(list,entry,DataSize,DataAddr);
  206.   IF CARDINAL(HIGH(Data))>=DataSize THEN
  207.     Data[DataSize]:=0;
  208.   ELSE
  209.     DataSize:=HIGH(Data)+1;
  210.   END;
  211.   CopyMem(DataAddr,ADR(Data),DataSize);
  212. END ReadEntryC;
  213.  
  214. PROCEDURE ReplaceEntry(list:List;
  215.                        entry:EntryPtr;
  216.                        DataSize:CARDINAL;
  217.                        DataAddr:ADDRESS);
  218. BEGIN
  219.   IF entry#NIL THEN
  220.     WITH entry^ DO
  221.       dataSize:=DataSize;
  222.       dataPtr:=DataAddr;
  223.     END;
  224.   ELSE
  225.     list^.listOk:=FALSE;
  226.   END;
  227. END ReplaceEntry;
  228.  
  229. PROCEDURE ReplaceEntryC(list:List;
  230.                         entry:EntryPtr;
  231.                     VAR Data:ARRAY OF BYTE);
  232. VAR     NewSize:LONGINT;
  233.         EndAddr:ADDRESS;
  234. BEGIN
  235.   IF entry#NIL THEN
  236.     NewSize:=HIGH(Data)+1;
  237.     WITH entry^ DO
  238.       IF LONGINT(dataSize)<=NewSize THEN
  239.         CopyMem(ADR(Data),dataPtr,dataSize);
  240.       ELSE
  241.         CopyMem(ADR(Data),dataPtr,NewSize);
  242.         EndAddr:=LONGINT(dataPtr)+NewSize;
  243.         EndAddr^:=0;
  244.       END;
  245.     END;
  246.   ELSE
  247.     list^.listOk:=FALSE;
  248.   END;
  249. END ReplaceEntryC;
  250.  
  251. PROCEDURE LocateEntryAbs(list:List;
  252.                          Position:CARDINAL):EntryPtr;
  253. VAR     entry:EntryPtr;
  254. BEGIN
  255.   IF Position<list^.numEntries THEN
  256.     entry:=ADDRESS(list^.header.head);
  257.     WHILE Position>0 DO
  258.       entry:=ADDRESS(entry^.node.succ);
  259.       DEC(Position);
  260.     END;
  261.     RETURN entry;
  262.   ELSE
  263.     list^.listOk:=FALSE;
  264.     RETURN NIL;
  265.   END;
  266. END LocateEntryAbs;
  267.  
  268. PROCEDURE LocateEntryRel(list:List;
  269.                      VAR entry:EntryPtr;
  270.                          Offset:INTEGER):BOOLEAN;
  271. VAR     Ok:BOOLEAN;
  272.         OldPos:EntryPtr;
  273. BEGIN
  274.   OldPos:=entry;
  275.   IF Offset>0 THEN
  276.     REPEAT
  277.       DEC(Offset);
  278.     UNTIL NOT Successor(entry) OR (Offset=0);
  279.     IF entry^.node.succ#NIL THEN
  280.       RETURN TRUE;
  281.     ELSE
  282.       entry:=OldPos;
  283.       RETURN FALSE;
  284.     END;
  285.   ELSIF Offset<0 THEN
  286.     REPEAT
  287.       INC(Offset);
  288.     UNTIL NOT Predecessor(entry) OR (Offset=0);
  289.     IF entry^.node.pred#NIL THEN
  290.       RETURN TRUE;
  291.     ELSE
  292.       entry:=OldPos;
  293.       RETURN FALSE;
  294.     END;
  295.   END;
  296. END LocateEntryRel;
  297.  
  298. PROCEDURE Successor(VAR entry:EntryPtr):BOOLEAN;
  299. BEGIN
  300.   entry:=ADDRESS(entry^.node.succ);
  301.   RETURN entry^.node.succ#NIL;
  302. END Successor;
  303.  
  304. PROCEDURE Predecessor(VAR entry:EntryPtr):BOOLEAN;
  305. BEGIN
  306.   entry:=ADDRESS(entry^.node.pred);
  307.   RETURN entry^.node.pred#NIL;
  308. END Predecessor;
  309.  
  310. PROCEDURE FirstEntry(list:List):EntryPtr;
  311. BEGIN
  312.   WITH list^ DO
  313.     IF header.head^.succ#NIL THEN
  314.       RETURN ADDRESS(header.head);
  315.     ELSE
  316.       list^.listOk:=FALSE;
  317.       RETURN NIL;
  318.     END;
  319.   END;
  320. END FirstEntry;
  321.  
  322. PROCEDURE LastEntry(list:List):EntryPtr;
  323. BEGIN
  324.   WITH list^ DO
  325.     IF header.tailPred^.pred#NIL THEN
  326.       RETURN ADDRESS(header.tailPred);
  327.     ELSE
  328.       list^.listOk:=FALSE;
  329.       RETURN NIL;
  330.     END;
  331.   END;
  332. END LastEntry;
  333.  
  334. BEGIN
  335.   ListsAllocProc:=Allocate;    (* default allocation procedure *)
  336.   ListsDeallocProc:=Deallocate;
  337. END Lists.
  338.  
  339.